﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CafeOnline.Common;
using CafeOnline.MvcFramework.Grid;

namespace CafeOnline.MvcFramework.Interfaces {
    public interface IColumnFactory {
        /// <summary>
        /// Enlist an action to be applied on a newly created column
        /// </summary>
        /// <param name="columnFormatting"></param>
        void AddFormatting(Action<Column> columnFormatting);

        /// <summary>
        /// Gets the metadata associated with the column
        /// </summary>
        IColumnFactoryMetadata Metadata {
            get;
        }

        /// <summary>
        /// Creates a new column for the specified gridID
        /// </summary>
        /// <param name="gridId">ID of the grid</param>
        /// <returns>Column created</returns>
        Column Create(string gridId);

        /// <summary>
        /// Gets the data associated with the column
        /// </summary>
        /// <param name="row"></param>
        /// <param name="additionalData"></param>
        /// <returns></returns>
        object GetData(BaseEntity row, IDictionary<string, object> additionalData);

        /// <summary>
        /// Filters based on user request.
        /// </summary>
        /// <param name="criteria"></param>
        /// <param name="rule"></param>
        void FilterData(object criteria, Rule rule);

        /// <summary>
        /// Sorts based on user request
        /// </summary>
        /// <param name="criteria"></param>
        /// <param name="order"></param>
        void SortData(object criteria, SortOrder order);

        /// <summary>
        /// Build object filtering when merged with in-memory list.
        /// </summary>
        /// <param name="rule"></param>
        /// <returns></returns>
        Func<object, bool> BuildFilterObject(Rule rule);

        /// <summary>
        /// Build sorting when merged with in-memory list.
        /// </summary>
        /// <param name="direction"></param>
        /// <returns></returns>
        Func<IEnumerable, IEnumerable> BuildSortObject(SortOrder direction);

        /// <summary>
        /// Type of the column
        /// </summary>
        ColumnType ColumnType { get; }
    }
    public interface IColumnFactoryMetadata {
        /// <summary>
        /// Defines the Type of grid.
        /// This a regular expression that can be used to include same grid in several objects.
        /// </summary>
        string GridType {
            get;
        }

        /// <summary>
        /// Defines the column name.
        /// </summary>
        string ColumnName {
            get;
        }

        /// <summary>
        /// Defines the label resource key.
        /// </summary>
        [DefaultValue("")]
        string LabelResourceKey {
            get;
        }

        /// <summary>
        /// Defines the label to display. It is used if no label resource key is defined.
        /// </summary>
        [DefaultValue("")]
        string Label {
            get;
        }

        /// <summary>
        /// Used when no custom sorting is implemented to have sorting on the grid.
        /// </summary>
        [DefaultValue("")]
        string SortingName {
            get;
        }

        /// <summary>
        /// Defines the default order of the column in the grid.
        /// </summary>
        int Order {
            get;
        }

        /// <summary>
        /// Priority of a given column against a similar one. Lower value defines a higher priority.
        /// Creating a new column with the same column name with a lower priority value will hide this current one.
        /// </summary>
        [DefaultValue(100)]
        int Priority {
            get;
        }

        /// <summary>
        /// Defines if the column is Hidden or not.
        /// </summary>
        [DefaultValue(false)]
        bool Hidden {
            get;
        }

        /// <summary>
        /// Specify if a column is excluded. It is used to overwrite a column using priority and then exclude it.
        /// It is typically used for hidding the number of codes generated for example.
        /// </summary>
        [DefaultValue(false)]
        bool Excluded {
            get;
        }

    }
}
